#ifndef __UTILITIES_H__
#define __UTILITIES_H__

#pragma once

#include "NezhaMemory.h"
#include "NezhaOS.h"

namespace Nezha
{

	// system time
	FOUNDATION_ENTRY s64 GetTimeMicroseconds();

	FOUNDATION_ENTRY u32 GetTimeMillisecond();

	FOUNDATION_ENTRY Real GetTimeSeconds();

	FOUNDATION_ENTRY void GetLocalTimeString(String& str);

	struct LocalTime
	{
		int Sec;
		int Min;
		int Hour;
		int Day;
		int Month;
		int Year;
		int DayInAWeek;
	};

	FOUNDATION_ENTRY void GetLocalTimeInfo(LocalTime& lt);

	// string hash func
	FOUNDATION_ENTRY u32 ElfHash(const char* str, bool uppercase = false);

	FOUNDATION_ENTRY u32 FNVHash(const char* str, bool uppercase = false);

	FOUNDATION_ENTRY u32 SimpleHash(const char* str, bool uppercase = false);

	class FOUNDATION_ENTRY StringUtil
	{
	public:
		static void Trim(_string& str, bool left = true, bool right = true);

		static void Split(const _string& str, StringArray& arr, const _string& delims = "\t\n", u32 maxSplits = 0,
			bool preserveDelims = false);

		template <typename T>
			static T Convert(const _string& str, T defValue)
		{
			_stringStream s(str);
			T v = defValue;
			s >> v;

			return v;
		}

	};

	// 2 dimension tpl
	template <typename T>
	class Tuple2
	{
	public:
		Tuple2(T X, T Y)
			: x(X), y(Y) {};


		Tuple2()
			: x(0), y(0) {};


		Tuple2(const Tuple2& rhs)
			: x(rhs.x), y(rhs.y) {};


		bool operator == (const Tuple2& rhs) const
		{
			return x == rhs.x && y == rhs.y;
		}


		bool operator != (const Tuple2& rhs) const
		{
			return x != rhs.x || y != rhs.y;
		}

		const Tuple2& operator+=(const Tuple2& rhs)
		{
			x += rhs.x;
			y += rhs.y;
			return *this;
		}

		const Tuple2& operator-=(const Tuple2& rhs)
		{
			x -= rhs.x;
			y -= rhs.y;
			return *this;
		}

		Tuple2 operator-(const Tuple2& rhs) const
		{
			return Tuple2(x-rhs.x, y-rhs.y);
		}

		Tuple2 operator+(const Tuple2& rhs) const
		{
			return Tuple2(x+rhs.x, y+rhs.y);
		}

		Tuple2 operator*(const Tuple2& rhs) const
		{
			return Tuple2(x*rhs.x, y*rhs.y);
		}

		Tuple2 operator*(const T& scalar) const
		{
			return Tuple2(x*scalar, y*scalar);
		}

		const Tuple2& operator=(const Tuple2& rhs) 
		{
			x = rhs.x;
			y = rhs.y;
			return *this;
		}

		T  x, y;
	};

	// 3 dimension tpl
	template <typename T>
	class Tuple3
	{
	public:
		Tuple3(T X, T Y, T Z)
			: x(X), y(Y), z(Z) {};


		Tuple3()
			: x(0), y(0), z(0) {};


		Tuple3(const Tuple3& rhs)
			: x(rhs.x), y(rhs.y), z(rhs.z) {};


		bool operator == (const Tuple3& rhs) const
		{
			return x == rhs.x && y == rhs.y && z == rhs.z;
		}


		bool operator != (const Tuple3& rhs) const
		{
			return x != rhs.x || y != rhs.y || z != rhs.z;
		}

		const Tuple3& operator += (const Tuple3& rhs)
		{
			x += rhs.x;
			y += rhs.y;
			z += rhs.z;

			return *this;
		}

		const Tuple3& operator-=(const Tuple3& rhs)
		{
			x -= rhs.x;
			y -= rhs.y;
			z -= rhs.z;
			return *this;
		}

		Tuple3 operator-(const Tuple3& rhs) const
		{
			return Tuple3(x-rhs.x, y-rhs.y, z-rhs.z);
		}

		Tuple3 operator+(const Tuple3& rhs) const
		{
			return Tuple3(x+rhs.x, y+rhs.y, z+rhs.z);
		}

		Tuple3 operator*(const Tuple3& rhs) const
		{
			return Tuple3(x*rhs.x, y*rhs.y, z*rhs.z);
		}

		Tuple3 operator*(const T& scalar) const
		{
			return Tuple3(x*scalar, y*scalar, z*scalar);
		}

		const Tuple3& operator=(const Tuple3& rhs) 
		{
			x = rhs.x;
			y = rhs.y;
			z = rhs.z;

			return *this;
		}

		T  x, y, z;
	};

	// 4 dimension tpl
	template <typename T>
	class Tuple4
	{
	public:
		Tuple4(T X, T Y, T Z, T W)
			: x(X), y(Y), z(Z), w(W) {};


		Tuple4()
			: x(0), y(0), z(0), w(0) {};


		Tuple4(const Tuple4& rhs)
			: x(rhs.x), y(rhs.y), z(rhs.z), w(rhs.w) {};


		bool operator == (const Tuple4& rhs) const
		{
			return x == rhs.x && y == rhs.y && z == rhs.z
				&& w = rhs.w;
		}


		bool operator != (const Tuple4& rhs) const
		{
			return x != rhs.x || y != rhs.y || z != rhs.z
				|| w != rhs.w;
		}

		const Tuple4& operator += (const Tuple4& rhs)
		{
			x += rhs.x;
			y += rhs.y;
			z += rhs.z;
			w += rhs.w;

			return *this;
		}

		const Tuple4& operator-=(const Tuple4& rhs)
		{
			x -= rhs.x;
			y -= rhs.y;
			z -= rhs.z;
			w -= rhs.w;

			return *this;
		}

		Tuple4 operator-(const Tuple4& rhs) const
		{
			return Tuple4(x-rhs.x, y-rhs.y, z-rhs.z, w-rhs.w);
		}

		Tuple4 operator+(const Tuple4& rhs) const
		{
			return Tuple4(x+rhs.x, y+rhs.y, z+rhs.z, w+rhs.w);
		}

		Tuple4 operator*(const Tuple4& rhs) const
		{
			return Tuple4(x*rhs.x, y*rhs.y, z*rhs.z, w*rhs.w);
		}

		Tuple4 operator*(const T& scalar) const
		{
			return Tuple4(x*scalar, y*scalar, z*scalar, w*scalar);
		}

		const Tuple4& operator=(const Tuple4& rhs) 
		{
			x = rhs.x;
			y = rhs.y;
			z = rhs.z;
			w = rhs.w;

			return *this;
		}

		T  x, y, z, w;
	};

	typedef Tuple2<Real> Pointf;
	typedef Tuple2<int> Pointi;

	typedef Tuple3<Real> Vec3f;
	typedef Tuple3<int> Vec3i;

	typedef Tuple4<Real> Vec4f;
	typedef Tuple4<int> Vec4i;


	// rectangle
	template <typename T>
	class Rect
	{
	public:

		Rect()
			:LeftCorner(0,0), RightCorner(0,0)
		{
		}

		Rect(T x, T y, T x2, T y2)
			:LeftCorner(x,y), RightCorner(x2,y2)
		{
		}

		Rect(Tuple2<T>& upperLeft, Tuple2<T>& lowerRight)
			:LeftCorner(upperLeft), RightCorner(lowerRight)
		{
		}

		Rect(const Rect& rhs)
			:LeftCorner(rhs.LeftCorner), RightCorner(rhs.RightCorner)
		{
		}

		Rect(Tuple2<T>& pos, T w, T h)
			:LeftCorner(pos), RightCorner(pos.x + w, pos.y + h)
		{
		}

		Rect operator+(Tuple2<T>& pos) const
		{
			Rect ret(*this);
			ret.LeftCorner += pos;
			ret.RightCorner += pos;
			return ret;
		}

		const Rect& operator+=(Tuple2<T>& pos)
		{
			LeftCorner += pos;
			RightCorner += pos;
			return *this;
		}

		Rect operator-(Tuple2<T>& pos) const
		{
			Rect ret(*this);
			ret.LeftCorner -= pos;
			ret.RightCorner -= pos;
			return ret;
		}

		const Rect& operator-=(Tuple2<T>& pos)
		{
			LeftCorner -= pos;
			RightCorner -= pos;
			return *this;
		}

		bool operator == (const Rect& rhs) const
		{
			return (LeftCorner == rhs.LeftCorner &&
				RightCorner == rhs.RightCorner);
		}


		bool operator != (const Rect& rhs) const
		{
			return (LeftCorner != rhs.LeftCorner ||
				RightCorner != rhs.RightCorner);
		}

		const Rect& operator = (const Rect& rhs)
		{
			LeftCorner = rhs.LeftCorner;
			RightCorner = rhs.RightCorner;
			return *this;
		}

		bool isPointInside(Tuple2<T>& pos) const
		{
			return (LeftCorner.x <= pos.x &&
				LeftCorner.y <= pos.y &&
				RightCorner.x >= pos.x &&
				RightCorner.y >= pos.y);
		}

		bool isRectInside(const Rect& rhs) const
		{
			return isPointInside(rhs.LeftCorner) &&
				isPointInside(rhs.RightCorner);
		}

		bool isRectCollided(const Rect& rhs) const
		{
			return (RightCorner.y > rhs.LeftCorner.y &&
				LeftCorner.y < rhs.RightCorner.y &&
				RightCorner.x > rhs.LeftCorner.x &&
				LeftCorner.x < rhs.RightCorner.x);
		}

		void clipAgainst(const Rect& rhs) 
		{
			if(rhs.RightCorner.x < RightCorner.x)
				RightCorner.x = rhs.RightCorner.x;
			if (rhs.RightCorner.y < RightCorner.y)
				RightCorner.y = rhs.RightCorner.y;

			if (rhs.LeftCorner.x > LeftCorner.x)
				LeftCorner.x = rhs.LeftCorner.x;
			if (rhs.LeftCorner.y > LeftCorner.y)
				LeftCorner.y = rhs.LeftCorner.y;

			if (LeftCorner.y > RightCorner.y)
				LeftCorner.y = RightCorner.y;
			if (LeftCorner.x > RightCorner.x)
				LeftCorner.x = RightCorner.x;
		}

		T getWidth() const
		{
			return RightCorner.x - LeftCorner.x;
		}

		T getHeight() const
		{
			return RightCorner.y - LeftCorner.y;
		}

		void repair()
		{
			if (RightCorner.x < LeftCorner.x)
			{
				T t = RightCorner.x;
				RightCorner.x = LeftCorner.x;
				LeftCorner.x = t;
			}

			if (RightCorner.y < LeftCorner.y)
			{
				T t = RightCorner.y;
				RightCorner.y = LeftCorner.y;
				LeftCorner.y = t;
			}
		}

		bool isValid() const
		{
			T xd = RightCorner.x - LeftCorner.x;
			T yd = RightCorner.y - LeftCorner.y;

			return !(xd < 0 || yd < 0 || (xd == 0 && yd == 0));
		}

		Tuple2<T> getCenter() const
		{
			return Tuple2<T>((LeftCorner.x + RightCorner.x) / 2,
				(LeftCorner.y + RightCorner.y) / 2);
		}

		Tuple2<T> getSize() const
		{
			return Tuple2<T>(getWidth(), getHeight());
		}

		void addInternalPoint(Tuple2<T>& p)
		{
			addInternalPoint(p.x, p.y);
		}

		void addInternalPoint(T x, T y)
		{
			if (x>RightCorner.x) RightCorner.x = x;
			if (y>RightCorner.y) RightCorner.y = y;

			if (x<LeftCorner.x) LeftCorner.x = x;
			if (y<LeftCorner.y) LeftCorner.y = y;
		}

		Tuple2<T> LeftCorner;
		Tuple2<T> RightCorner;

	};

	typedef Rect<float> Rectf;
	typedef Rect<int>   RectI;

	typedef u32 ColorDW;

	inline void NZColorClamp(float &x) 
	{ 
		x = (float)(x < 0.0 ? 0.0 : (x > 1.0 ? 1.0 : x));
	}

	/** color RGBA */
	class FOUNDATION_ENTRY RGBA
	{
	public:
		RGBA()
			:r(0), g(0), b(0), a(1)
		{
		}

		RGBA(float fR, float fG, float fB, float fA)
			:r(fR), g(fG), b(fB), a(fA)
		{
		}

		RGBA(const RGBA &rgba)
			:r(rgba.r), g(rgba.g), b(rgba.b), a(rgba.a)
		{
		}

		RGBA& operator= (const RGBA &rgba)
		{
			r = rgba.r;
			g = rgba.g;
			b = rgba.b;
			a = rgba.a;
			return *this;
		}

		bool operator== (const RGBA &rgba) const
		{
			return r == rgba.r && g == rgba.g && b == rgba.b
				&& a == rgba.a;
		}

		bool operator!= (const RGBA &rgba) const
		{
			return r != rgba.r || g != rgba.g || b != rgba.b
				|| a != rgba.a;
		}

		RGBA operator + (const RGBA &rgba) const
		{
			return RGBA(r+rgba.r, g+rgba.g, b+rgba.b, a+rgba.a);
		}

		RGBA operator - (const RGBA &rgba) const
		{
			return RGBA(r-rgba.r, g-rgba.g, b-rgba.b, a-rgba.a);
		}

		RGBA operator * (const RGBA &rgba) const
		{
			return RGBA(r*rgba.r, g*rgba.g, b*rgba.b, a*rgba.a);
		}

		RGBA operator * (float fScalar) const
		{
			return RGBA(fScalar*r, fScalar*g, fScalar*b, fScalar*a);
		}

		RGBA& operator += (const RGBA &rgba)
		{
			r += rgba.r;
			g += rgba.g;
			b += rgba.b;
			a += rgba.a;
			return *this;
		}

		RGBA& operator -= (const RGBA &rgba)
		{
			r -= rgba.r;
			g -= rgba.g;
			b -= rgba.b;
			a -= rgba.a;
			return *this;
		}

		RGBA& operator *= (const RGBA &rgba)
		{
			r *= rgba.r;
			g *= rgba.g;
			b *= rgba.b;
			a *= rgba.a;
			return *this;
		}

		RGBA& operator *= (float fScalar)
		{
			r *= fScalar;
			g *= fScalar;
			b *= fScalar;
			a *= fScalar;
			return *this;
		}

		ColorDW getDW_ARGB() const;

		ColorDW getDW_RGBA() const;

		void setDW_ARGB(ColorDW dw);

		void setDW_RGBA(ColorDW dw);

		void clamp()
		{
			NZColorClamp(r);
			NZColorClamp(g);
			NZColorClamp(b);
			NZColorClamp(a);
		}

		static const RGBA BLACK;
		static const RGBA WHITE;
		static const RGBA RED;
		static const RGBA GREEN;
		static const RGBA BLUE;
		static const RGBA INVALID;

		float r, g, b, a;
	};

	inline RGBA operator * (float fScalar, const RGBA &rgba)
	{ 
		return RGBA(fScalar*rgba.r, fScalar*rgba.g, fScalar*rgba.b,
			fScalar*rgba.a);
	}

	// HSV color needed?

	//! Sinks an element into the heap.
	template<class T>
	inline void heapsink(T*array, int element, int max)
	{
		while ((element<<1) < max) // there is a left child
		{
			int j = (element<<1);

			if (j+1 < max && array[j] < array[j+1])
				j = j+1; // take right child

			if (array[element] < array[j])
			{
				T t = array[j]; // swap elements
				array[j] = array[element];
				array[element] = t;
				element = j;
			}
			else
			return;
		}
	}


	//! Sorts an array with size 'size' using heapsort.
	template<class T>
	inline void heapsort(T* array_, int size)
	{
		// for heapsink we pretent this is not c++, where
		// arrays start with index 0. So we decrease the array pointer,
		// the maximum always +2 and the element always +1

		T* virtualArray = array_ - 1;
		int virtualSize = size + 2;
		int i;

		// build heap

		for (i=((size-1)/2); i>=0; --i)
			heapsink(virtualArray, i+1, virtualSize-1);

		// sort array

		for (i=size-1; i>=0; --i)
		{
			T t = array_[0];
			array_[0] = array_[i];
			array_[i] = t;
			heapsink(virtualArray, 1, i + 1);
		}
	}

	class FOUNDATION_ENTRY PrimeNumber
	{
	public:
		static bool Test(u32 n);

		static u32 MakePrimeGreaterThan(u32 n);

		// return 0 if found no such prime number.
		static u32 MakePrimeLessThan(u32 n);

		//static const u16 msPrimeNumbersBelow1000[];
	};

	inline int NZRand()
	{
		return rand();
	}

	inline float NZUnitRandom()
	{
		return float(NZRand()) / float(RAND_MAX);
	}

	class NZRandom
	{
	public:
		static void SetSeed(u32 seed);

		// range [min, max)
		static int Rangei(int iMin, int iMax);

		// range [min, max]
		static float Rangef(float fMin, float fMax);

	private:
		static u32 msSeed;
	};


	// default string hash founctor 4 DoubleLayersHashMap.
	class FOUNDATION_ENTRY DefStrDoubleHashFunctor
	{
	public:
		inline u32 hash1(const _string& s)
		{
			mHash1 = SimpleHash(s.c_str());
			return mHash1;
		}

		inline u32 hash2(const _string& s)
		{
			//return FNVHash(s.c_str());
			return mHash1 * 214013;
		}

		u32 mHash1;
	};

	const u32 DoubleHashMapReserve = 509;
	const u16 DoubleHashMapGarbReserve = 64;

	// default double layers hashing map storage.
	// second layer can be auto growing Quadratic probing map or something(for default using chain map).
	template <typename T, typename Key>
	class DoubleLayersHashMapBase
	{
	public:
		class Slot
		{
		public:
			u8 mStatus;
			Key mOrigKey;
			u32 mHK;
			T mPtr;

			Slot()
				:mStatus(0)
				,mHK(0)
			{
			}

			bool empty() const
			{
				return mStatus == 0;
			}

			bool equal(u32 hk, const Key& k) const
			{
				return hk == mHK && mOrigKey == k;
			}
		};

		class ChainSlot
		{
		public:
			u8 mStatus;
			Key mOrigKey;
			ChainSlot* mNext;
			T mPtr;

			ChainSlot()
				:mStatus(0)
				,mNext(NULL)
			{
			}

			bool empty() const
			{
				return mStatus == 0;
			}
		};

		DoubleLayersHashMapBase()
			:mNumOccupied(0)
			,mTableLength(0)
			,mCapcity(0)
			,mSlots(NULL)
			,mChainSlots(NULL)
		{
		}

		~DoubleLayersHashMapBase()
		{
			if(mSlots)
			{
				NZ_Delete []mSlots;
			}

			if(mChainSlots)
			{
				for(u32 i = 0; i < mTableLength; i++)
				{
					deleteChainSlot(mChainSlots[i].mNext);
				}

				NZ_Delete [] mChainSlots;
			}
		}

		// must be called beofre using.
		void initStorage(u32 len)
		{
			mTableLength = len;
			mNumOccupied = 0;
			allocateReserve();
		}

		void occupy(u32 pos, const T& val, u32 hk, const Key& k)
		{
			mSlots[pos].mPtr = val;
			mSlots[pos].mHK = hk;
			mSlots[pos].mOrigKey = k;
			mSlots[pos].mStatus = 1;

			++mNumOccupied;
		}

		// occupy second layer
		void occupy2(u32 pos, const T& val, u32 hk, const Key& k)
		{
			ChainSlot* cs = NULL;

			if(mChainSlots[pos].empty())
			{
				cs = &mChainSlots[pos];
			}
			else
			{
				ChainSlot* p = &mChainSlots[pos];

				while(p)
				{
					if(p->empty())
					{
						cs = p;
						break;
					}

					if(p->mNext)
					{
						p = p->mNext;
					}
					else
					{
						p->mNext = NZ_New ChainSlot();
						++mCapcity;
						cs = p->mNext;
						break;
					}
				}
			}

			cs->mPtr = val;
			cs->mOrigKey = k;
			cs->mStatus = 1;

			++mNumOccupied;
		}

		bool keyExist(u32 pos1, u32 pos2) const
		{
			if(!mSlots[pos1].empty())
			{
				return true;
			}

			ChainSlot* cs = &mChainSlots[pos2];

			while(cs)
			{
				if(!cs->empty())
				{
					return true;
				}

				cs = cs->mNext;
			}

			return false;
		}

		bool retrieve2(u32 pos, const Key& key, T& v)
		{
			ChainSlot* cs = &mChainSlots[pos];

			while(cs)
			{
				if(!cs->empty() && key == cs->mOrigKey)
				{
					v = cs->mPtr;
					return true;
				}

				cs = cs->mNext;
			}

			return false;
		}

		void clear(u32 pos)
		{
			if(!mSlots[pos].empty())
			{
				mSlots[pos].mStatus = 0;
				--mNumOccupied;
			}
		}

		bool clear2(u32 pos, const Key& k)
		{
			ChainSlot* cs = &mChainSlots[pos];
			if(!cs->empty() && k == cs->mOrigKey)
			{
				cs->mStatus = 0;
				--mNumOccupied;
				return true;
			}

			ChainSlot* prev = cs;
			cs = cs->mNext;

			while(cs)
			{
				if(!cs->empty() && k == cs->mOrigKey)
				{
					prev->mNext = cs->mNext;
					NZ_Delete cs;				// maybe use a garbage cache?
					--mNumOccupied;
					return true;
				}

				prev = cs;
				cs = cs->mNext;
			}

			return false;
		}

		void deleteChainSlot(ChainSlot* cs)
		{
			while(cs)
			{
				ChainSlot* tmp = cs->mNext;
				NZ_Delete cs;
				cs = tmp;
			}
		}

		void clearAll()
		{
			mNumOccupied = 0;
			if(mSlots &&  mCapcity > mTableLength * 2)
			{
				NZ_Delete [] mSlots;

				for(u32 i = 0; i < mTableLength; i++)
				{
					deleteChainSlot(mChainSlots[i].mNext);
				}

				NZ_Delete [] mChainSlots;

				allocateReserve();
			}
		}

		u32 numOccupied() const
		{
			return mNumOccupied;
		}

		u32 tableLength() const
		{
			return mTableLength;
		}

		u32 capcity() const
		{
			return mCapcity;
		}

		Slot& operator[] (u32 index)
		{
			return mSlots[index];
		}

		ChainSlot& secondLayer(u32 index)
		{
			return mChainSlots[index];
		}

	private:
		void allocateReserve()
		{
			mSlots = NZ_New Slot[mTableLength];
			mChainSlots = NZ_New ChainSlot[mTableLength];
			mCapcity = mTableLength << 1;
		}

		// support no assign directly??
		void operator = (const DoubleLayersHashMapBase& dlhm){}

	private:
		Slot* mSlots;
		ChainSlot* mChainSlots;
		u32 mNumOccupied;
		u32 mTableLength;
		u32 mCapcity;
	};


	/** double layers hash map for pointers and tiny structures.
	*/
	template <typename T, typename Key, class HashFunc, class HashTableStorage = DoubleLayersHashMapBase<T, Key> >
	class DoubleLayersHashMap
	{
	public:
		bool keyExist(const Key& key) const
		{
			u32 hk1 = mFounctor.hash1(key);
			u32 tableLen = mTable.tableLength();
			u32 pos1 = hk1 % tableLen;
			u32 hk2 = mFounctor.hash2(key);
			hk2 = hk2 % tableLen;

			return mTable.keyExist(hk1, hk2);
		}

		void insert(const Key& key, const T& val)
		{
			u32 hk1 = mFounctor.hash1(key);

			u32 tableLen = mTable.tableLength();
			u32 pos1 = hk1 % tableLen;
			
			if(mTable[pos1].empty())
			{
				mTable.occupy(pos1, val, hk1, key);
			}
			else
			{
				u32 hk2 = mFounctor.hash2(key);
				hk2 = hk2 % tableLen;

				mTable.occupy2(hk2, val, hk1, key);
			}
		}

		bool search(const Key& key, T& ret)
		{
			u32 hk1 = mFounctor.hash1(key);

			u32 tableLen = mTable.tableLength();
			u32 pos1 = hk1 % tableLen;

			if(!mTable[pos1].empty())
			{
				if(mTable[pos1].equal(hk1, key))
				{
					ret = mTable[pos1].mPtr;
					return true;
				}
			}

			u32 hk2 = mFounctor.hash2(key);
			hk2 = hk2 % tableLen;

			return mTable.retrieve2(hk2, key, ret);
		}

		bool remove(const Key& key)
		{
			u32 hk1 = mFounctor.hash1(key);

			u32 tableLen = mTable.tableLength();
			u32 pos1 = hk1 % tableLen;

			if(!mTable[pos1].empty())
			{
				if(mTable[pos1].equal(hk1, key))
				{
					mTable.clear(pos1);
					return true;
				}
			}

			u32 hk2 = mFounctor.hash2(key);
			hk2 = hk2 % tableLen;

			return mTable.clear2(hk2, key);
		}

		void clear()
		{
			mTable.clearAll();
		}

		DoubleLayersHashMap()
		{
			mTable.initStorage(DoubleHashMapReserve);
		}

		DoubleLayersHashMap(u32 initialSize)
		{
			if(!PrimeNumber::Test(initialSize))
			{
				initialSize = PrimeNumber::MakePrimeGreaterThan(initialSize);
			}

			mTable.initStorage(initialSize);
		}

	private:

		// support no assign directly??
		void operator = (const DoubleLayersHashMap& dlhm){}

	private:
		HashTableStorage mTable;
		HashFunc mFounctor;
	};

}//end namespace Nezha

#endif //end __UTILITIES_H__